package Algorithm.sort.basic;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 桶排序：根据待排序的数据范围划分出若干个区间（即桶），遍历数组将每个元素放到对应区间的桶中，然后对每个桶进行内部排序，最后将各个桶中的元素依次取出，即构成有序序列
 */
public class BucketSort {

    public static void main(String[] args) {
        int[] A = new int[]{5,6,1,2,3,6,9};
        bucketSort(A, 3);
        System.out.println(Arrays.toString(A));
    }

    static void bucketSort(int[] A, int bucketSize) {
        int min = A[0], max = A[0];
        //寻找最小元素和最大元素
        for (int i = 1; i < A.length; i++) {
            if (min > A[i])
                min = A[i];
            if (max < A[i])
                max = A[i];
        }
        //根据数据范围和桶的大小确定桶的数量
        int bucketCount = (max-min)/bucketSize + 1;
        ArrayList[] buckets = new ArrayList[bucketCount];
        for (int i=0;i < bucketCount;i++) {
            buckets[i] = new ArrayList<Integer>();
        }
        //扫描数组将元素放到对应的桶中
        for (int i=0;i < A.length;i++) {
            //A[i]所属桶的编号
            int k = (A[i]-min)/bucketSize;
            buckets[k].add(A[i]);
        }
        //对每个桶进行内部排序然后依次取出，构成有序序列
        for (int k=0, i=0;k < bucketCount;k++) {
            buckets[k].sort(null);
            for (int j=0;j < buckets[k].size();j++) {
                A[i++] = (Integer)buckets[k].get(j);
            }
        }
    }
}
